package dai.samples.shiro.config;

import dai.samples.shiro.config.session.MySessionListener;
import dai.samples.shiro.config.session.dao.MySessionDAO;
import dai.samples.shiro.config.session.scheduler.MyValidatingSessionManager;
import org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler;
import org.apache.shiro.session.mgt.ValidatingSessionManager;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * shiro 会话管理有关的配置，正常来说，配置应该要相对集中。
 * 这里拆分开是因为此demo中包含多个功能点，为了防止混淆所以如此操作
 */
@Configuration
public class ShiroSessionConfig {

    /**
     * 会话CRUD
     * @return
     */
    @Autowired
    private MySessionDAO sessionDAO;


    /**
     * 获取session管理器，三种默认实现
     * DefaultSessionManager：DefaultSecurityManager 使用的默认实现，用于 JavaSE 环境；
     * ServletContainerSessionManager：DefaultWebSecurityManager 使用的默认实现，用于 Web 环境，其直接使用 Servlet 容器的会话；
     * DefaultWebSessionManager：用于 Web 环境的实现，可以替代 ServletContainerSessionManager，自己维护着会话，直接废弃了 Servlet 容器的会话管理。
     * @return
     */
    @Bean
    public DefaultWebSessionManager defaultWebSessionManager (@Autowired MyCacheManager cacheManager) {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();

        // 会话CRUD的操作
        sessionManager.setSessionDAO(sessionDAO);
        // 会话监听器
        sessionManager.getSessionListeners().add(new MySessionListener());
        // sessionManager.setSessionListeners(new ArrayList<>());
        // 创建会话 Cookie 的模板
        sessionManager.setSessionIdCookie(getCookie());
        // 是否启用 / 禁用 Session Id Cookie，默认是启用的
        //sessionManager.setSessionIdCookieEnabled(null);
        //sessionManager.setSessionIdUrlRewritingEnabled(null);
        // session管理器自己的缓存管理
        // sessionManager.setCacheManager(cacheManager);
        // 会话验证器，用来验证会话是否过期
        sessionManager.setSessionValidationScheduler(getExecutorServiceSessionValidationScheduler());
        // 是否开启会话验证，默认开启
        // sessionManager.setSessionValidationSchedulerEnabled(true);
        return sessionManager;
    }

    /**
     * 会话的cookie
     * @return
     */
    private Cookie getCookie() {
        Cookie cookie = new SimpleCookie();
        // 设置 Cookie 名字，默认为 JSESSIONID
        cookie.setName("dai-JSESSIONID");
        // 设置 Cookie 的域名，默认空，即当前访问的域名
        // cookie.setDomain("");
        // 设置 Cookie 的路径，默认空，即存储在域名根下
        // cookie.setPath("");
        // 设置 Cookie 的过期时间，秒为单位，默认 - 1 表示关闭浏览器时过期 Cookie
        cookie.setMaxAge(1000);
        // 如果设置为 true，则客户端不会暴露给客户端脚本代码
        cookie.setHttpOnly(false);
        return cookie;
    }

    /**
     * 会话验证调度器,用来执行会话过期验证
     * @return
     */
    private ExecutorServiceSessionValidationScheduler getExecutorServiceSessionValidationScheduler() {
        ExecutorServiceSessionValidationScheduler scheduler = new ExecutorServiceSessionValidationScheduler();
        // 验证间隔
        scheduler.setInterval(1000*60*30);
        // 设置会话验证管理器
        scheduler.setSessionManager(getValidatingSessionManager());
        return scheduler;
    }

    /**
     * 会话验证管理器，
     * 用来验证会话过期
     * @return
     */
    private ValidatingSessionManager getValidatingSessionManager() {
        MyValidatingSessionManager validatingSessionManager = new MyValidatingSessionManager();
        // 这里可以设置自己需要的参数
        validatingSessionManager.setSessionDAO(sessionDAO);
        return validatingSessionManager;
    }


}
